package com.yunsc.order.sevice.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunsc.common.exception.YunscException;
import com.yunsc.common.utils.PageResult;
import com.yunsc.media.service.YunscUploadFileService;
import com.yunsc.order.dao.YunscOrderRefundDao;
import com.yunsc.order.dto.ApplyOrderRefundDTO;
import com.yunsc.order.dto.OrderRefundDTO;
import com.yunsc.order.dto.QueryOrderRefundDTO;
import com.yunsc.order.entity.*;
import com.yunsc.order.sevice.*;
import com.yunsc.order.vo.OrderRefundVO;
import com.yunsc.store.dao.YunscRegionDao;
import com.yunsc.store.entity.YunscStoreAddressEntity;
import com.yunsc.store.service.YunscStoreAddressService;
import com.yunsc.store.service.YunscUserService;
import com.yunsc.store.vo.AddressRegionVO;
import com.yunsc.store.vo.StoreAddressVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@Service("yunscOrderRefundService")
public class YunscOrderRefundServiceImpl extends ServiceImpl<YunscOrderRefundDao, YunscOrderRefundEntity> implements YunscOrderRefundService {

    @Resource
    private YunscUploadFileService uploadFileService;
    @Resource
    private YunscStoreAddressService storeAddressService;
    @Resource
    private YunscOrderRefundAddressService orderRefundAddressService;
    @Resource
    private YunscOrderRefundImageService orderRefundImageService;
    @Resource
    private YunscOrderGoodsService orderGoodsService;
    @Resource
    private YunscRegionDao regionDao;
    @Resource
    private YunscOrderService ordersService;
    @Resource
    private YunscUserService userService;
    @Resource
    private YunscOrderRefundService orderRefundService;


    @Override
    public PageResult<OrderRefundVO> queryRefundOrders(QueryOrderRefundDTO orderRefundDTO, Integer storeId) {
        Page<OrderRefundVO> pageResult = this.baseMapper.selectOrderRefundPage(
                new Page<>(orderRefundDTO.getPage(), orderRefundDTO.getPageSize()), orderRefundDTO, storeId);
        pageResult.getRecords().forEach(orderRefund -> {
            orderRefund.getOrderGoods().setGoodsImage(uploadFileService.queryFileUrlById(orderRefund.getOrderGoods().getImageId()));
            orderRefund.getUser().setAvatarUrl(uploadFileService.queryFileUrlById(orderRefund.getUser().getAvatarId()));
        });
        return PageResult.formatPageResult(pageResult.getRecords(), orderRefundDTO.getPage(), orderRefundDTO.getPageSize(), pageResult.getTotal());
    }

    @Override
    public void auditOrderRefund(OrderRefundDTO param) {
        Integer orderRefundId = param.getOrderRefundId();
        YunscOrderRefundEntity orderRefund = this.getById(orderRefundId);
        if (orderRefund == null) {
            throw new YunscException("售后订单不存在");
        }
        // 是否同意
        Integer auditStatus = param.getForm().getAuditStatus();
        if (auditStatus == 10) {
            // 同意退货，设置商家地址
            // 获取当前实现类的代理对象
            orderRefundService.auditAgree(param, orderRefund, auditStatus);
        }
        if (auditStatus == 20) {
            // 拒绝退货，设置拒绝原因
            orderRefundService.refuseAudit(param, orderRefund, auditStatus);
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void refuseAudit(OrderRefundDTO param, YunscOrderRefundEntity orderRefund, Integer auditStatus) {
        String refuseDesc = param.getForm().getRefuseDesc();
        if (StringUtils.isEmpty(refuseDesc)) {
            throw new YunscException("请输入拒绝原因");
        }
        // 修改售后订单状态
        orderRefund.setAuditStatus(auditStatus);
        orderRefund.setStatus(auditStatus);
        orderRefund.setRefuseDesc(param.getForm().getRefuseDesc());
        boolean update = this.updateById(orderRefund);
        if (!update) {
            throw new YunscException("售后订单审核失败");
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void auditAgree(OrderRefundDTO param, YunscOrderRefundEntity orderRefund, Integer auditStatus) {
        Integer orderRefundId = orderRefund.getOrderRefundId();
        YunscStoreAddressEntity storeAddress = storeAddressService.getById(param.getForm().getAddressId());
        if (storeAddress == null){
            throw new YunscException("售后订单地址不存在");
        }
        YunscOrderRefundAddressEntity orderRefundAddress = orderRefundAddressService.getOne(new QueryWrapper<YunscOrderRefundAddressEntity>().eq("order_refund_id", orderRefundId));
        if (orderRefundAddress == null){
            orderRefundAddress = new YunscOrderRefundAddressEntity();
            orderRefundAddress.setOrderRefundId(orderRefundId);
            BeanUtils.copyProperties(storeAddress, orderRefundAddress);
            boolean save = orderRefundAddressService.save(orderRefundAddress);
            if (!save) {
                throw new YunscException("售后订单地址添加失败");
            }
        }else {
            orderRefundAddress.setOrderRefundId(orderRefundId);
            BeanUtils.copyProperties(storeAddress, orderRefundAddress);
            boolean save = orderRefundAddressService.updateById(orderRefundAddress);
            if (!save) {
                throw new YunscException("售后订单地址添加失败");
            }
        }
        // 判断订单是否发货
        YunscOrderGoodsEntity orderGoodsEntity = orderGoodsService.getById(orderRefund.getOrderGoodsId());
        if (orderGoodsEntity.getDeliveryStatus() == 10) {
            // 订单未发货，退款给用户
            // 修改售后订单状态
            orderRefund.setStatus(20); // 已完成
            // 退款给用户
            String orderNo = ordersService.getById(orderRefund.getOrderId()).getOrderNo();
            userService.orderRefundMoney(orderNo, orderRefund.getRefundMoney(), orderRefund.getRefundPoints(), orderRefund.getUserId());
        }
        // 修改售后订单状态
        orderRefund.setAuditStatus(auditStatus);
        boolean update = this.updateById(orderRefund);
        if (!update) {
            throw new YunscException("售后订单审核失败");
        }

        // 修改订单状态
        // 判断订单中的商品是否全部是售后订单的商品
        int orderGoodsCount = orderGoodsService.count(new QueryWrapper<YunscOrderGoodsEntity>().eq("order_id", orderRefund.getOrderId()));
        int orderRefundCount = this.count(new QueryWrapper<YunscOrderRefundEntity>().eq("order_id", orderRefund.getOrderId()));
        if (orderGoodsCount ==  orderRefundCount){
            // 订单中全部是售后订单的商品，修改订单状态
            ordersService.update(new UpdateWrapper<YunscOrderEntity>().eq("order_id", orderRefund.getOrderId()).set("order_status", 20));
        }
    }

    @Override
    public OrderRefundVO queryRefundOrderDetail(Integer orderRefundId) {
        YunscOrderRefundEntity orderRefund = this.getById(orderRefundId);
        if (orderRefund == null) {
            throw new YunscException("售后订单不存在");
        }
        OrderRefundVO orderRefundVO = this.baseMapper.selectOrderRefundDetail(orderRefundId);
        orderRefundVO.getOrderGoods().setGoodsImage(uploadFileService.queryFileUrlById(orderRefundVO.getOrderGoods().getImageId()));
        orderRefundVO.getUser().setAvatarUrl(uploadFileService.queryFileUrlById(orderRefundVO.getUser().getAvatarId()));
        LambdaQueryWrapper<YunscOrderRefundImageEntity> lqw = new LambdaQueryWrapper<YunscOrderRefundImageEntity>().eq(YunscOrderRefundImageEntity::getOrderRefundId, orderRefundId);
        List<YunscOrderRefundImageEntity> list = orderRefundImageService.list(lqw);
        list.forEach(image -> {
            image.setImageUrl(uploadFileService.queryFileUrlById(image.getImageId()));
        });
        orderRefundVO.setImages(list);
        YunscOrderRefundAddressEntity address = orderRefundAddressService.getOne(new LambdaQueryWrapper<YunscOrderRefundAddressEntity>()
                .eq(YunscOrderRefundAddressEntity::getOrderRefundId, orderRefundId));
        if (address != null) {
            StoreAddressVO addressVO = new StoreAddressVO();
            BeanUtils.copyProperties(address, addressVO);
            AddressRegionVO regionVO = regionDao.getAddressVOByOrderId(address.getRegionId());
            addressVO.setRegion(regionVO);
            orderRefundVO.setAddress(addressVO);
        }
        return orderRefundVO;
    }

    @Override
    public PageResult<OrderRefundVO> queryUserRefundOrder(Integer state, Integer page, Integer userId) {
        LambdaQueryWrapper<YunscOrderRefundEntity> lqw = new LambdaQueryWrapper<>();
        lqw.eq(YunscOrderRefundEntity::getUserId, userId);
        if (state == 0) {
            // 待处理（audit_status == 0）
            lqw.eq(YunscOrderRefundEntity::getStatus, 0);
        }
        lqw.orderByAsc(YunscOrderRefundEntity::getCreateTime);

        // 全部
        Page<YunscOrderRefundEntity> pageResult = this.page(new Page<>(page, 15), lqw);

        List<OrderRefundVO> collect = pageResult.getRecords().stream().map(orderGoods -> {
            OrderRefundVO orderRefundVO = new OrderRefundVO();
            BeanUtils.copyProperties(orderGoods, orderRefundVO);
            formatOrderRefund(orderRefundVO);
            return orderRefundVO;
        }).collect(Collectors.toList());

        return PageResult.formatPageResult(collect, page, 15, pageResult.getTotal());
    }

    @Override
    @Transactional
    public void applyOrderRefund(ApplyOrderRefundDTO param, Integer userId) {
        YunscOrderRefundEntity orderRefund = new YunscOrderRefundEntity();
        YunscOrderGoodsEntity orderGoods = orderGoodsService.getById(param.getOrderGoodsId());
        if (null == orderGoods){
            throw new YunscException("订单商品不存在");
        }
        orderRefund.setOrderId(orderGoods.getOrderId());
        orderRefund.setOrderGoodsId(orderGoods.getOrderGoodsId());
        orderRefund.setUserId(userId);
        orderRefund.setApplyDesc(param.getForm().getContent());
        orderRefund.setType(param.getForm().getType());
        orderRefund.setRefundMoney(orderGoods.getTotalPayPrice());
        orderRefund.setStoreId(orderGoods.getStoreId());
        boolean save = this.save(orderRefund);
        if (!save){
            throw new YunscException("申请售后失败");
        }
        List<Integer> images = param.getForm().getImages();
        if (CollectionUtils.isNotEmpty(images)) {
            List<YunscOrderRefundImageEntity> imageList = new ArrayList<>();
            for (Integer image : images) {
                YunscOrderRefundImageEntity imgEntity =  new YunscOrderRefundImageEntity();
                imgEntity.setOrderRefundId(orderRefund.getOrderRefundId());
                imgEntity.setImageId(image);
                imgEntity.setStoreId(orderGoods.getStoreId());
                imageList.add(imgEntity);
            }
            orderRefundImageService.saveBatch(imageList);
        }
    }

    @Override
    public void refundOrderDelivery(OrderRefundDTO param, Integer userId) {
        Integer orderRefundId = param.getOrderRefundId();
        YunscOrderRefundEntity orderRefund = this.getOne(new QueryWrapper<YunscOrderRefundEntity>()
                .eq("order_refund_id", orderRefundId).eq("user_id", userId));
        if (orderRefund == null) {
            throw new YunscException("售后订单不存在");
        }
        orderRefund.setIsUserSend(1);
        orderRefund.setSendTime((int) (System.currentTimeMillis() / 1000));
        orderRefund.setExpressId(String.valueOf(param.getForm().getExpressId()));
        orderRefund.setExpressNo(param.getForm().getExpressNo());
        boolean update = this.updateById(orderRefund);
        if (!update) {
            throw new YunscException("售后订单发货失败");
        }
    }

    @Override
    public OrderRefundVO queryUserRefundOrderDetail(Integer orderRefundId) {
        YunscOrderRefundEntity orderRefund = this.getById(orderRefundId);
        if (orderRefund == null) {
            throw new YunscException("售后订单不存在");
        }
        OrderRefundVO orderRefundVO = this.baseMapper.selectOrderRefundDetail(orderRefundId);
        orderRefundVO.getOrderGoods().setGoodsImage(uploadFileService.queryFileUrlById(orderRefundVO.getOrderGoods().getImageId()));
        LambdaQueryWrapper<YunscOrderRefundImageEntity> lqw = new LambdaQueryWrapper<YunscOrderRefundImageEntity>().eq(YunscOrderRefundImageEntity::getOrderRefundId, orderRefundId);
        List<YunscOrderRefundImageEntity> list = orderRefundImageService.list(lqw);
        list.forEach(image -> {
            image.setImageUrl(uploadFileService.queryFileUrlById(image.getImageId()));
        });
        orderRefundVO.setImages(list);
        formatOrderRefund(orderRefundVO);
        return orderRefundVO;
    }


    private void formatOrderRefund(OrderRefundVO orderRefund) {
        // orderRefund.setCreateTime(DateFormatUtils.formatDatetime(orderRefund.getCreateTime()));
        orderRefund.setOrderGoods(orderGoodsService.queryOrderGoodsById(orderRefund.getOrderGoodsId()));
        // 商家审核状态(0待审核 10已同意 20已拒绝)
        Integer auditStatus = orderRefund.getAuditStatus();
        if (auditStatus == 0) {
            orderRefund.setStateText("等待审核中");
        } else if (auditStatus == 20) {
            orderRefund.setStateText("已拒绝");
        } else if (auditStatus == 10) {
            orderRefund.setStateText("已同意退货，请及时发货");
        }
    }
}